﻿using ServerBase.Config;
using SvGame.Objects;
using static System.Net.Mime.MediaTypeNames;

namespace SvGame.Logic;

public static partial class GameLogic
{
    public static bool NewRoom(ConfigRoomExt confext, out Room obj)
    {
        obj =  new();
        obj.Uid = confext.Id;
        obj.CfgExt = confext;
       
        obj.SetExits();

        obj.RoomUpdate();
        return true;
    }
    public static void SetExits(this Room room)
    {
        foreach (var text in room.Cfg.Exits)
        {
            if (GetExit(room, text, out var exit))
            {
                room.DictExit[exit.Dir] = exit;
            }
        }
        // 自定义出口
        foreach (var list in room.Cfg.ExitsExtra)
        {
            if (list.Count >= 2)
            {
                if (GetExitExtra(list[0], list[1], out var exit))
                {
                    room.DictExit[exit.Dir] = exit;
                }
            }
        }
    }
    public static bool GetExit(Room room, string text, out RoomExit exit)
    {
        exit = new RoomExit()
        {
            Dir = text,
        };
        if (text.IsNullOrEmpty())
        {
            return false;
        }
        exit.RoomUid = exit.Dir switch
        {
            "e" => room.Uid + 100,
            "w" => room.Uid - 100,
            "s" => room.Uid - 1,
            "n" => room.Uid + 1,
            "se" => room.Uid + 100 - 1,
            "sw" => room.Uid - 100 - 1,
            "ne" => room.Uid + 100 + 1,
            "nw" => room.Uid - 100 + 1,
            _ => room.Uid,
        };
        return true;
    }
    public static bool GetExitExtra(string text, string exitName, out RoomExit exit)
    {
        exit = new RoomExit()
        {
            Dir = text,
        };
        exit.RoomUid = exitName.ToLong();
        //if (!GetRoom(exitName.ToLong(), out var room))
        //{
        //    return false;
        //}
        return true;
    }
    public static void RoomUpdate(this Room room)
    {
        var confext = room.CfgExt;

        foreach (var kvp in confext.DictItems)
        {
            room.AddItem(kvp.Key, kvp.Value);
        }
        foreach (var kvp in confext.DictEquips)
        {
            room.AddEquip(kvp.Key, kvp.Value);
        }
        foreach (var kvp in confext.DictNpcs)
        {
            room.AddNpc(kvp.Key, kvp.Value);
        }
    }
    public static bool AddItem(this Room room, Item obj)
    {
        obj.Env = room;
        room.DictItem[obj.Uid] = obj;

        obj.InitCallouts();

        return true;
    }
    public static bool AddItem(this Room room, int configId, int count)
    {
        if (count <= 0)
        {
            loger.Warn($"Room AddItem 数目错误 configId{configId} Count{count}");
            return false;
        }
        if (!ConfItemExt.TryGetValue(configId, out var conf))
        {
            loger.Warn($"Room AddItem 道具配置错误 ConfigId{configId}");
            return false;
        }
        if (conf.SettBase.Stackable)
        {
            var obj = (from it in room.DictItem.Values
                        where (it.ConfigId == configId)
                        select it).FirstOrDefault();
            if (obj is not null)
            {
                obj.Count += count;
            }
            else
            {
                if (NewItem(conf, count, out obj))
                {
                    room.AddItem(obj);
                }
            }
        }
        else
        {
            for (int i = 0; i < count; i++)
            {
                if (NewItem(conf, 1, out var obj))
                {
                    room.AddItem(obj);
                }
            }
        }
        return true;
    }
    public static void RemoveItem(this Room room, long uid)
    {
        room.DictItem.Remove(uid);
    }
    public static bool AddEquip(this Room room, int configId, int count)
    {
        if (configId == 0)
        {
            return false;
        }
        if (count <= 0)
        {
            loger.Warn($"Room AddEquip 数目错误 configId{configId} Count{count}");
            return false;
        }
        if (!ConfEquip.TryGetValue(configId, out var conf))
        {
            loger.Warn($"Room AddEquip 装备配置错误 ConfigId{configId}");
            return false;
        }
        for (int i = 0; i < count; i++)
        {
            if (NewEquip(conf, out var obj))
            {
                obj.Env = room;
                room.DictEquip[obj.Uid] = obj;
            }
        }
        return true;
    }
    public static bool AddNpc(this Room room, int configId, int count)
    {
        if (configId == 0)
        {
            return false;
        }
        if (count <= 0)
        {
            loger.Warn($"Room AddNpc 数目错误 configId{configId} Count{count}");
            return false;
        }
        if (!ConfNpcExt.TryGetValue(configId, out var conf))
        {
            loger.Warn($"Room AddNpc 装备配置错误 ConfigId{configId}");
            return false;
        }
        for (int i = 0; i < count; i++)
        {
            if (NewNpc(conf, out var obj))
            {
                obj.Room = room;
                room.DictNpc[obj.Uid] = obj;
            }
        }
        return true;
    }
    public static void RemoveNpc(this Room room, long uid)
    {
        room.DictNpc.Remove(uid);
    }
    
}
